package com.csxh.web.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 反射工具类
 * 
 * @author hp
 *
 */
public class ReflectUtil {

	/**
	 * 获取所有符合正则匹配的方法
	 * 
	 * @param regex
	 * @param clazz
	 * @param includeAll
	 *            TODO
	 * @return
	 */
	public static Method[] findMethods(String regex, Class<?> clazz, String[] excludes, boolean includeAll) {
		List<Method> retList = new ArrayList<>();
		// 获取本类定义的所有方法
		Method[] methods = clazz.getDeclaredMethods();
		Pattern p = Pattern.compile(regex);

		for (Method method : methods) {
			if (!ArrayUtil.contains(method.getName(),excludes)) {
				Matcher m = p.matcher(method.getName());
				if (m.find()) {
					retList.add(method);
				}
			}
		}

		if (includeAll) {
			// 获取从父类继承过来的所有方法
			methods = clazz.getMethods();
			for (Method method : methods) {
				if (ArrayUtil.contains(method.getName(),excludes)) {
					Matcher m = p.matcher(method.getName());
					if (m.find()) {
						retList.add(method);
					}
				}
			}
		}

		return retList.toArray(new Method[retList.size()]);
	}

	/**
	 * 获取指定类型中的所有形如：getXxxx的方法
	 * 
	 * @param clazz
	 * @param excludes
	 *            排序指定的方法名称
	 * @return
	 */
	public static Method[] findGetMethods(Class<?> clazz, String... excludes) {

		String regex = "^get[A-Z]\\w*$";
		return findMethods(regex, clazz, excludes, false);
	}

	/**
	 * 获取getXxx方法的值
	 * @param clazz
	 * @param xxxx
	 * @return
	 */
	public static Method findGetMethod(Class<?> clazz, String xxxx) {

		StringBuilder sb = new StringBuilder();
		sb.append("get").append(StringUtil.toUpperFirstChar(xxxx));
		String getXxx = sb.toString();
		// 获取所有形如：getXxx的方法反射对象
		Method[] methods = findGetMethods(clazz);
		for (Method method : methods) {
			if (getXxx.equals(method.getName())) {
				return method;
			}
		}
		return null;

	}

	public static Method[] findSetMethods(Class<?> clazz,String...excludes) {

		String regex = "^set[A-Z]\\w*$";
		return findMethods(regex, clazz,excludes, false);
	}

	public static Method findSetMethod(Class<?> clazz, String xxxx,Class<?>... parameterTypes) {

		StringBuilder sb = new StringBuilder();
		sb.append("set").append(StringUtil.toUpperFirstChar(xxxx));
		String setXxx = sb.toString();
		// 获取所有形如：getXxx的方法反射对象
		Method[] methods = findSetMethods(clazz);
		for (Method method : methods) {
			
			if (setXxx.equals(method.getName())) {

				int paramCount=parameterTypes.length;
				if(paramCount>0){
					paramCount=0;
					for (Class<?> param : method.getParameterTypes()) {
						for (Class<?> param2 : parameterTypes) {
							if (param.equals(param2)) {
								paramCount++;
							}
						}
					}
					if(paramCount==parameterTypes.length){
						return method;
					}
				}else{					
					return method;
				}
			}
		}
		return null;

	}
	
}
